﻿using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using WalkingTec.Mvvm.Mvc;
using TyMES.ViewModel.Record.MaterialPDVMs;
using TyMES.Model.Record;
using TyMES.Communication;
using TyMES.Communication.Request;
using TyMES.Services;
using System.Threading.Tasks;
using TyMES.Model.BaseInformation;
using System.Text.RegularExpressions;
using TyMES.PassStationCommunication;


namespace TyMES.Controllers
{
    [Area("Record")]
    [AuthorizeJwtWithCookie]
    [ActionDescription("泰国电驱轴系生产数据")]
    [ApiController]
    [Route("api/MaterialPD")]
	public partial class MaterialPDController : BaseApiController
    {
        private readonly PassStationService passStationService;

        public MaterialPDController(PassStationService passStationService)
        {
            this.passStationService = passStationService;
        }   

        [ActionDescription("Sys.Search")]
        [HttpPost("Search")]
		public IActionResult Search(MaterialPDSearcher searcher)
        {
            if (ModelState.IsValid)
            {
                var vm = Wtm.CreateVM<MaterialPDListVM>(passInit: true);
                vm.Searcher = searcher;
                return Content(vm.GetJson());
            }
            else
            {
                return BadRequest(ModelState.GetErrorJson());
            }
        }

        [ActionDescription("Sys.Get")]
        [HttpGet("{id}")]
        public MaterialPDVM Get(string id)
        {
            var vm = Wtm.CreateVM<MaterialPDVM>(id);
            return vm;
        }

        [ActionDescription("Sys.Create")]
        [HttpPost("Add")]
        public IActionResult Add(MaterialPDVM vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                vm.DoAdd();
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }

        }

        [ActionDescription("Sys.Edit")]
        [HttpPut("Edit")]
        public IActionResult Edit(MaterialPDVM vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                vm.DoEdit(false);
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }
        }

		[HttpPost("BatchDelete")]
        [ActionDescription("Sys.Delete")]
        public IActionResult BatchDelete(string[] ids)
        {
            var vm = Wtm.CreateVM<MaterialPDBatchVM>();
            if (ids != null && ids.Count() > 0)
            {
                vm.Ids = ids;
            }
            else
            {
                return Ok();
            }
            if (!ModelState.IsValid || !vm.DoBatchDelete())
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                return Ok(ids.Count());
            }
        }


        [ActionDescription("Sys.Export")]
        [HttpPost("ExportExcel")]
        public IActionResult ExportExcel(MaterialPDSearcher searcher)
        {
            var vm = Wtm.CreateVM<MaterialPDListVM>();
            vm.Searcher = searcher;
            vm.SearcherMode = ListVMSearchModeEnum.Export;
            return vm.GetExportData();
        }

        [ActionDescription("Sys.CheckExport")]
        [HttpPost("ExportExcelByIds")]
        public IActionResult ExportExcelByIds(string[] ids)
        {
            var vm = Wtm.CreateVM<MaterialPDListVM>();
            if (ids != null && ids.Count() > 0)
            {
                vm.Ids = new List<string>(ids);
                vm.SearcherMode = ListVMSearchModeEnum.CheckExport;
            }
            return vm.GetExportData();
        }

        [ActionDescription("Sys.DownloadTemplate")]
        [HttpGet("GetExcelTemplate")]
        public IActionResult GetExcelTemplate()
        {
            var vm = Wtm.CreateVM<MaterialPDImportVM>();
            var qs = new Dictionary<string, string>();
            foreach (var item in Request.Query.Keys)
            {
                qs.Add(item, Request.Query[item]);
            }
            vm.SetParms(qs);
            var data = vm.GenerateTemplate(out string fileName);
            return File(data, "application/vnd.ms-excel", fileName);
        }

        [ActionDescription("Sys.Import")]
        [HttpPost("Import")]
        public ActionResult Import(MaterialPDImportVM vm)
        {
            if (vm!=null && (vm.ErrorListVM.EntityList.Count > 0 || !vm.BatchSaveData()))
            {
                return BadRequest(vm.GetErrorJson());
            }
            else
            {
                return Ok(vm?.EntityList?.Count ?? 0);
            }
        }

        [ActionDescription("上传轴系生产参数")]
        [HttpPost("UploadMaterialPD")]
        public  ResponseBase UploadMaterialPD(MaterialPD pD)
        {
            try
            {
                pD.uploadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm;ss");
                DC.Set<MaterialPD>().Add(pD);
                DC.SaveChanges();
                return new ResponseBase(true, "");
            }
            catch (Exception ex)
            {
                return new ResponseBase(false, ex.Message);
            }
        }

        public record CheckRequest(string materialSN,string stationCode,string FSN);

        [ActionDescription("查询加工结果")]
        [HttpPost("CheckMaterialPD")]
        public async Task<ResponseBase> CheckMaterialPD(CheckRequest request)
        {
            try
            {

                //啮合结果校验
                if (!string.IsNullOrEmpty(request.materialSN))
                {
                    var GMJudgeResult = await passStationService.CheckGearMeshResult(request.materialSN);
                    if (!GMJudgeResult.Success)
                        return GMJudgeResult;
                }
                if (!string.IsNullOrEmpty(request.FSN))
                {
                    var GMJudgeResult2 = await passStationService.CheckGearMeshResult(request.FSN);
                    if (!GMJudgeResult2.Success)
                        return GMJudgeResult2;
                }
                

                //查看当前工位是否需要进行附料校验
                var FL_Station = DC.Set<CustomConfig>().Where(x => x.customProperty == "FLJudgeStaton").First().propertyValue;
                var FL_Station2 = DC.Set<CustomConfig>().Where(x => x.customProperty == "FLJudgeStaton_2").First().propertyValue;
                if (request.stationCode != null)//&&(request.materialSN==""&&request.materialSN==null)
                {
                    if (FL_Station.Contains(request.stationCode))
                    {
                        var LastProcessInfo = DC.Set<MaterialPD>().Where(x => x.CurrentSN == request.FSN).ToList();
                        if (LastProcessInfo.Count==0)
                        {
                            return new ResponseBase(false, "未查询到附料加工结果");
                        }
                        foreach (var info in LastProcessInfo)
                        {
                            if (info.result == "NG")
                            {
                                return new ResponseBase(false, "附料加工结果NG");
                            }
                        }
                        return new ResponseBase(true, "仅校验附料，加工结果OK");
                    }
                    if (FL_Station2.Contains(request.stationCode))
                    {
                        var LastProcessInfo_2 = DC.Set<MaterialPD>().Where(x => x.AnotherSN == request.materialSN).ToList();
                        if (LastProcessInfo_2.Count == 0)
                        {
                            return new ResponseBase(false, "未查询"+request.materialSN+"作为附料加工结果");
                        }
                        foreach (var info in LastProcessInfo_2)
                        {
                            if (info.result == "NG")
                            {
                                return new ResponseBase(false, request.materialSN + "作为附料的加工结果NG");
                            }
                        }
                        return new ResponseBase(true, request.materialSN + "作为附料的加工结果OK");
                    }

                }

                return new ResponseBase(true, "加工结果OK");
            }
            catch (Exception ex)
            {
                return new ResponseBase(false, ex.Message);
            }
        }

        [ActionDescription("扫码选垫")]
        [HttpPost("ScanToSelectPad")]
        public async Task<SelectPadResquest> ScanToSelectPad(SelectPadResquest res)
        {
            SelectPadResquest selectPad = new SelectPadResquest();
            StationLogRecord stationLog = new StationLogRecord();
            try
            {


                //Pattern为false是选垫模式，true是查询模式
                selectPad.Pattern = res.Pattern;

                if (res.Pattern)
                {
                    //查询模式
                    var GetSN = DC.Set<MaterialBindRecord>().Where(x => x.AssemblyMaterialSn == res.scanData).FirstOrDefault();
                    if (GetSN == null)
                    {
                        await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "未查询到物料" + res.scanData + "的上线绑定记录");
                        return selectPad;
                    }
                    //selectPad.SelectFlag = res.SelectFlag;
                    var Padselect_Exist = DC.Set<MaterialPD>().Where(x=>(x.CurrentSN== GetSN .SnNumber|| x.AnotherSN== GetSN.SnNumber) &&x.OperationCode==res.stationCode).OrderByDescending(x=>x.ID).FirstOrDefault();
                    if (Padselect_Exist == null)
                    {
                        await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "未查询到物料" + res.scanData + "的选垫记录");
                        return selectPad;
                    }
                    
                    List<string> qx_datas = new List<string>();
                    List<string> tz_datas = new List<string>();
                    qx_datas=await passStationService.QXPadSelectData(Padselect_Exist.AnotherSN);
                    if(qx_datas.Count==0)
                    {
                        await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "未查询到物料前箱测深数据");
                        return selectPad;
                    }
                    tz_datas=await passStationService.TZPadSelectData(Padselect_Exist.CurrentSN);
                    if (tz_datas.Count == 0)
                    {
                        await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "未查询到物料后箱测高数据");
                        return selectPad;
                    }
                    selectPad.TZSN = Padselect_Exist.CurrentSN;
                    selectPad.QXSN = Padselect_Exist.AnotherSN;
                    char[] delimiterChars = { '*' };
                    string[] OrignalData = Padselect_Exist.PDdata.Split(delimiterChars);
                    string[] datas = OrignalData.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
                    selectPad.CType = datas[0];
                    selectPad.FZType = datas[1];
                    selectPad.FType = datas[2];

                    selectPad.LQC = qx_datas[0];
                    selectPad.LQFZ = qx_datas[1];
                    selectPad.LQF = qx_datas[2];
                    selectPad.QXAssmeblyCode = qx_datas[3];

                    selectPad.LHC = tz_datas[0];
                    selectPad.LHFZ = tz_datas[1];
                    selectPad.LHF = tz_datas[2];
                    selectPad.TZAssmeblyCode = tz_datas[3];
                    
                    double lqc = double.Parse(selectPad.LQC);//差速器深度
                    double lqfz = double.Parse(selectPad.LQFZ);//副轴深度
                    double lqf = double.Parse(selectPad.LQF);//发动机轴深度
                    double lhc = double.Parse(selectPad.LHC);//差速器高度
                    double lhfz = double.Parse(selectPad.LHFZ);//副轴深度
                    double lhf = double.Parse(selectPad.LHF);//发动机轴高度

                    double tcd = lqc - lhc + 0.05;//差速器区间左值
                    double tcu = lqc - lhc + 0.12;//差速器区间右值
                    double tfzd = lqfz - lhfz;//副轴区间左值
                    double tfzu = lqfz - lhfz + 0.1;//副轴区间右值
                    double tfu = lqf - lhf - 0.02;//发动机轴区间右值
                    double tfd = lqf - lhf - 0.08;//发动机轴区间左值

                    selectPad.TCU = tcu.ToString("F2");
                    selectPad.TCD = tcd.ToString("F2");
                    selectPad.TFZU = tfzu.ToString("F2");
                    selectPad.TFZD = tfzd.ToString("F2");
                    selectPad.TFU = tfu.ToString("F2");
                    selectPad.TFD = tfd.ToString("F2");

                    selectPad.lineCode = res.lineCode;
                    selectPad.stationCode = res.stationCode;
                    return selectPad;
                }


                var isQX = await passStationService.CheckIsQX(res);
                if (isQX.Success)
                {
                    //获取前箱测深工位号
                    var CSStation = DC.Set<CustomConfig>().Where(x=>x.customProperty== "QXCSStationCode").First().propertyValue;
                    var GetSN = DC.Set<MaterialBindRecord>().Where(x => x.AssemblyMaterialSn == res.scanData).FirstOrDefault();
                    if (GetSN == null)
                    {
                        await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "未查询到此电机上线绑定记录");
                        return selectPad;
                    }
                    else
                    {
                        //判断是否已完成过绑定
                        var PadSelect_result_Exist = DC.Set<MaterialPD>().Where(x => x.AnotherSN == GetSN.SnNumber && x.OperationCode == res.stationCode).OrderByDescending(x => x.ID).FirstOrDefault();
                        if (PadSelect_result_Exist != null)
                        {
                            await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "前箱SN["+GetSN.SnNumber+"]已完成过选垫绑定");
                            return selectPad;
                        }

                        var MeasureDepth = DC.Set<MaterialPD>().Where(x => x.CurrentSN == GetSN.SnNumber&&x.OperationCode==CSStation).OrderByDescending(x=>x.ID).FirstOrDefault();
                        if (MeasureDepth == null)
                        {
                            await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "未查询到" + GetSN.SnNumber + "的测高记录");
                            return selectPad;
                        }
                        else
                        {
                            char[] delimiterChars = { '*' };
                            string[] OrignalData = MeasureDepth.PDdata.Split(delimiterChars);
                            string[] datas = OrignalData.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
                            //List<string> SelectTypes =await passStationService.GetPadTypes();
                            selectPad.QXAssmeblyCode = res.scanData;
                            selectPad.QXSN = GetSN.SnNumber;
                            selectPad.LQC = datas[0];
                            selectPad.LQFZ = datas[1];
                            selectPad.LQF = datas[2];

                            //获取当前过站sn
                            ResponseComSN getTZSN =  passStationService.FindPassStationSN(res.lineCode,res.stationCode);

                            if (!getTZSN.Success)
                            {
                               await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad",getTZSN.SN );
                                return selectPad;
                            }

                           //测电机轴高度工位
                            var CHStation = DC.Set<CustomConfig>().Where(x => x.customProperty == "TZCHStationCode").First().propertyValue;
                            
                           //绑定的电机物料信息
                            var TZFirstStation = DC.Set<CustomConfig>().Where(x => x.customProperty == "TZFirstStationCode").First().propertyValue;
                            var TZMaterialBindRecord = DC.Set<MaterialBindRecord>().Where(x=>x.StationCode==TZFirstStation&&x.SnNumber==getTZSN.SN).FirstOrDefault();
                            if (TZFirstStation == null)
                            {
                                await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "SN:[" + getTZSN.SN + "]上线未绑定电机号");
                                return selectPad;
                            }
                            
                           //判断是否已完成过选垫绑定
                           var PadSelect_TZresult_Exist = DC.Set<MaterialPD>().Where(x => x.CurrentSN == getTZSN.SN&& x.OperationCode == res.stationCode).OrderByDescending(x => x.ID).FirstOrDefault();
                           if (PadSelect_TZresult_Exist != null)
                           {
                               await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "后箱SN[" + getTZSN.SN + "]已完成过选垫绑定");
                               return selectPad;
                           }

                           var MeasureHigh = DC.Set<MaterialPD>().Where(x => x.CurrentSN == getTZSN.SN && x.OperationCode == CHStation).OrderByDescending(x => x.ID).FirstOrDefault();
                           if (MeasureHigh == null)
                           {
                               await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", "未查询到" + getTZSN.SN + "的测高记录");
                               return selectPad;
                           }
                           else
                           {
                               //char[] delimiterChars = { '*' };
                               string[] TZOrignalData = MeasureHigh.PDdata.Split(delimiterChars);
                               string[] TZdatas = TZOrignalData.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
                               List<string> SelectTypes = await passStationService.GetPadTypes();
                               //selectPad.QXAssmeblyCode = res.QXAssmeblyCode;
                               selectPad.TZAssmeblyCode = TZMaterialBindRecord.AssemblyMaterialSn;
                               //selectPad.QXSN = res.QXSN;
                               selectPad.TZSN = getTZSN.SN;
                               selectPad.LHC = TZdatas[0];
                               selectPad.LHFZ = TZdatas[1];
                               selectPad.LHF = TZdatas[2];
                               //selectPad.LQC = res.LQC;
                               //selectPad.LQFZ = res.LQFZ;
                               //selectPad.LQF = res.LQF;

                               double lqc = double.Parse(selectPad.LQC);//差速器深度
                               double lqfz = double.Parse(selectPad.LQFZ);//副轴深度
                               double lqf = double.Parse(selectPad.LQF);//发动机轴深度
                               double lhc = double.Parse(selectPad.LHC);//差速器高度
                               double lhfz = double.Parse(selectPad.LHFZ);//副轴深度
                               double lhf = double.Parse(selectPad.LHF);//发动机轴高度

                               double tcd = lqc - lhc + 0.05;//差速器区间左值
                               double tcu = lqc - lhc + 0.12;//差速器区间右值
                               double tfzd = lqfz - lhfz;//副轴区间左值
                               double tfzu = lqfz - lhfz + 0.1;//副轴区间右值
                               double tfu = lqf - lhf - 0.02;//发动机轴区间右值
                               double tfd = lqf - lhf - 0.08;//发动机=轴区间左值

                               selectPad.TCU = tcu.ToString("F2");
                               selectPad.TCD = tcd.ToString("F2");
                               selectPad.TFZU = tfzu.ToString("F2");
                               selectPad.TFZD = tfzd.ToString("F2");
                               selectPad.TFU = tfu.ToString("F2");
                               selectPad.TFD = tfd.ToString("F2");

                               if (SelectTypes[0] == "thick")//差速器选薄
                                   selectPad.CType = (tcu - tcu % 0.05).ToString("F2");
                               else
                                   selectPad.CType = (tcd - tcd % 0.05 + 0.05).ToString("F2");

                               if (SelectTypes[1] == "thick")//副轴选薄
                                   selectPad.FZType = (tfzu - tfzu % 0.05).ToString("F2");
                               else
                                   selectPad.FZType = (tfzd - tfzd % 0.05 + 0.05).ToString("F2");

                               if (SelectTypes[2] == "thick")//发动机轴选厚
                                   selectPad.FType = (tfu - tfu % 0.05).ToString("F2");
                               else
                                   selectPad.FType = (tfd - tfd % 0.05 + 0.05).ToString("F2");


                               
                               selectPad.lineCode = res.lineCode;
                               selectPad.stationCode = res.stationCode;
                               passStationService.SavePadSelectResult(selectPad);
                               await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, "", "good", "前箱[" + selectPad.QXSN + "]测深值与后箱[" + selectPad.TZSN + "]测高值完成选垫绑定");
                               return selectPad;
                           }
                           
                        }
                    }
                }
                else
                {
                    await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", $"扫入条码[{res.scanData}]不符合前箱物料条码规则，请检查");
                    return selectPad;
                }
                



            }
            catch (Exception ex)
            {
                await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad",ex.Message);
                return selectPad;
            }

            


        }

        [ActionDescription("删除选垫结果")]
        [HttpPost("PadSelectDataDelete")]
        public async Task<ResponseBase> PadSelectDataDelete(SelectPadResquest res)
        {
            StationLogRecord stationLog = new StationLogRecord();
            try
            {
                var deleteRow =  DC.Set<MaterialPD>().Where(x => x.OperationCode == res.stationCode && x.CurrentSN == res.TZSN).ToList();
                DC.Set<MaterialPD>().RemoveRange(deleteRow);
                DC.SaveChanges();
                await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, "", "good", "删除前箱[" + res.QXSN + "]测深值与后箱[" + res.TZSN + "]测高值的选垫结果，可重对两个物料重新扫码选垫");
                return new ResponseBase(true, "删除前箱[" + res.QXSN + "]测深值与后箱[" + res.TZSN + "]测高值的选垫结果，可重对两个物料重新扫码选垫");
            }
            catch (Exception ex)
            {
                await passStationService.stationlogadd(stationLog, res.lineCode, res.stationCode, res.scanData, "bad", ex.Message);
                return new ResponseBase(false,ex.Message);
            }
        }

    }
}
